12. 메서드(함수): 좋은 클래스에는 좋은 메서드가 있다
📌 Contents
📌 반드시 현재 클래스의 인스턴스 변수 사용하기
- 인스턴스 변수를 안전하게 조작하도록 메서드를 설계하면, 클래스 내부가 정상적인 상태인지 보장할 수 있음(3장 참고)
- 메서드는 반드시 현재 클래스의 인스턴스 변수를 사용하도록 설계하는 것이 기본 원칙
- 다른 클래스의 인스턴스 변수를 변경하는 메서드는 응집도가 낮은 구조가 될 수 있어 좋지 않음
- 다른 클래스의 인스턴스 변수를 변경하는 메서드를 작성하고 싶다면, 변경된 내용을 다루는 새로운 인스턴스를 생성하고 이를 리턴하는 형태로 구현하는 것이 좋음
📌 불변을 활용해서 예상할 수 있는 메서드 만들기
- 가변 인스턴스 변수 등을 변경하는 메서드는 의도하지 않게 다른 부분에 영향을 줘, 예상치 못한 동작이 발생할 수 있고, 유지보수가 어려워 짐(4.2.2절 참고)
- 불변을 활용해서 예상치 못한 동작 자체를 막을 수 있게 설계하라
📌 묻지 말고 명령하라
- 어떤 클래스가 다른 클래스의 상태를 판단하거나, 상태에 따라 값을 변경하는 등 '다른 클래스를 확인하고 조작하는 메서드 구조'는 응집도가 낮은 구조
- 인스턴스 변수의 값을 추출하는 메서드인 getter나 값을 설정하는 메서드인 setter는 '다른 클래스를 확인하고 조작하는 메서드 구조'가 되기 쉬움
- 메서드를 호출하는 쪽에서는 복잡한 처리를 하지 않는 것이 좋음
- '묻지 말고 명령하라' 접근 방법이 유효
- 호출되는 메서드 쪽에서 복잡한 처리를 하는 형태로 만드는 것이 좋음
📌 커맨드/쿼리 분리
- 상태 변경과 추출을 동시에 하는 메서드는 여러 문제의 원인이 됨
- 추출만 하고 싶거나 변경만 하고 싶을 때 지원하지 못함
- 메서드는 커맨드 또는 쿼리 중에 하나만 하도록 설계해야 한다는
커맨드-쿼리 분리(CQS, Command-Query Separation)
패턴이 있음
- 커맨드: 상태를 변경하는 것
- 쿼리: 상태를 리턴하는 것
- 모디파이어: 커맨드와 쿼리를 동시에 하는 것
- 상황에 따라 모디파이어로 만들 수밖에 없는 메서드도 있지만, 그건 예외이고 최대한 피하는 것이 좋음
📌 매개변수
불변 매개변수로 만들기
- 매개변수를 변경하면 의미가 바뀌어서, 어떤 의미를 나타내는지 유추하기 어려움
- 매개변수를 변경하고 싶으면, 불변 지역 변수를 만들고, 여기에 변경 값을 할당하는 형태로 구현(4.1.2절 참고)
플래그 매개변수 사용하지 않기
- 플래그 매개변수(boolean 자료형의 매개변수)를 받는 메서드는 코드를 읽는 사람이 메서드가 무슨일을 하는지 알기 어렵게 만듬(6.6절 참고)
- 전략 패턴 등의 다른 구조로 설계하기
null 전달하지 않기
- null을 활용하는 로직은 NullPointerException이 발생할 수 있으며, null을 확인해야 하므로 로직이 복잡해지는 등 다양한 문제를 일으킴(9.6절 참고)
- null을 전달하지 않게 설계하려면, null에 의미를 부여해서는 안됨
출력 매개변수 사용하지 않기
- 출력 매개변수를 사용하면 응집도가 낮은 구조가 만들어짐(5.4절 참고)
- 매개변수는 입력 값으로 사용하는 것이 기본이라 출력 값으로 사용하면, 코드를 읽는 사람에게 혼란을 줄 수 있음
매개변수는 최대한 적게 사용하기
- 메서드에 매개변수가 많다는 것은 메서드가 여러 가지 기능을 처리하는다는 의미
- 메서드가 처리할 게 많아지면, 그만큼 로직이 복잡해져 이는 다양한 악마들을 불러들임
📌 리턴 값
'자료형'을 사용해서 리턴 값의 의도 나타내기
- int 자료형처럼 단순한 기본 자료형으로는 리턴한 값의 의미를 호출하는 쪽에 전달할 수 없음
- 따라서 기본 자료형을 사용하지 말고, 독자적인 자료형을 사용해서 의도를 명확하게 나타내는 것이 좋음
null 리턴하지 않기
- 매개변수로 null을 전달하지 않는 것이 좋듯이, null을 리턴하지 않아야 좋음
오류는 리턴 값으로 리턴하지 말고 예외 발생시키기
- 위치를 이동시키는 메서드에서 이동 후의 좌표가 잘못 . 된경우, 오류 값으로 Loaction(-1, -1)을 리턴하게 된다면,
- 호출하는 쪽에서 '오류가 있을 때, 오류 값으로 Location(-1, -1)을 리턴한다'라는 사실을 알고 있어야 하고, 이를 활용해서 오류 처리를 확실하게 구현해야 함
- 어떤 값으로 여러 의미를 나타내는 것을
중의적(double meaning)
이라고 함
- Location(-1, -1)처럼 특정한 값의 좌표가 아니라, 오류도 다루는 것을 중의적이라고 함
- 중의적으로 쓰면 상황에 따라 의미가 달라지므로, 읽는 사람에게 혼란을 줌
- 또한 상황 판단을 위해 조건 분기를 사용해야 하므로, 조건 분기가 이곳저곳 늘어남
- 잘못된 상태에는 어떠한 관용도 배풀어서는 안됨
- 리턴 값으로 오류 값을 리턴하지 말고, 곧바로 예외를 발생시켜야 함